﻿/***
    Copyright 2012 Stijn Van Antwerpen
  
    This file is part of Qasparov.

    Qasparov is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Qasparov is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Qasparov. If not, see <http://www.gnu.org/licenses/>.

 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SDK = Com.Oxilly.Qsb.Core.SDK;
using LinqToTwitter;


/* Note: This Extension use OAth for authentication to Twitter
 * The consumerKey and secret need to be provided at run time. If you want to reuse this module, you need to
 * create your own Twitter application and use it's own credentials.
 * See: http://dev.twitter.com/apps
*/

namespace Com.Oxilly.Qasparov.Twitter
{
    class TwitterQApp : SDK.EF.QAppBase
    {

        public const String OAUTH_CONFIGURATE = "com.oxilly.qasparov.twitter.oath_config";
        public const String OAUTH_CONSUMER_KEY = "ConsumerKey";
        public const String OAUTH_CONSUMER_SECRET = "ConsumerSecret";
        public const String OAUTH_OATH_TOKEN = "OAuthToken";
        public const String OAUTH_ACCESS_TOKEN = "AccessToken";
        public const String QASPAROV_TWITTER_STATUSUPDATE = "Qasparov.Twitter.StatusUpdate";

        TwitterContext twitterCtx;

        #region QApp Lifecycle
        protected override void OnActivate(SDK.QsbEngineApi api)
        {
            CreateTwitterContext();   
        }

        private void CreateTwitterContext()
        {
            var auth = Authenticate();
            if (auth.IsAuthorized)
            {
                this.twitterCtx = new TwitterContext(authorization: auth);
            }
            else
            {
                this.twitterCtx = null;
                Log(String.Format("Authentication of {0} for Twitter failed.", this.Name), System.Diagnostics.SourceLevels.Warning);
            }         
        }
        #endregion

        #region QApp Events
        protected override bool Filter(SDK.QsbEngineApi api, SDK.Events.QsbEventArgs e)
        {
            //Accept everything
            return true;
        }

        protected override void OnQsbEvent(SDK.QsbEngineApi api, SDK.Events.QsbEventArgs e)
        {
            if (this.twitterCtx != null)
            {
                this.twitterCtx.UpdateStatus(e.Description);
            }
        }

        protected override void OnQsbMessageReceived(SDK.QsbEngineApi api, SDK.API.QsbMessage message)
        {
            switch (message.MessageType)
            {
                case OAUTH_CONFIGURATE: Configure(message);
                    break;
                case QASPAROV_TWITTER_STATUSUPDATE: UpdateTwitterStatus(message);
                    break;
            }
        }

        private void UpdateTwitterStatus(SDK.API.QsbMessage message)
        {
            if (twitterCtx == null)
            {
                CreateTwitterContext();
            }
            this.twitterCtx.UpdateStatus(
                message.MessageAttributes["Status"]);
        }        
        #endregion

        #region private methods

        private ITwitterAuthorizer Authenticate()
        {
            var consumerKey = Properties.Settings.Default.ConsumerKey;
            var consumerSecret = Properties.Settings.Default.ConsumerSecret;
            var oAuthToken = Properties.Settings.Default.OAuthToken;
            var accessToken = Properties.Settings.Default.AccessToken;

            var auth = new SingleUserAuthorizer
            {
                Credentials = new SingleUserInMemoryCredentials
                {
                    ConsumerKey = consumerKey,
                    ConsumerSecret = consumerSecret,
                    OAuthToken = oAuthToken,
                    AccessToken = accessToken
                }
            };
            
            auth.Authorize();

            return auth;
        }

        private void Configure(SDK.API.QsbMessage message)
        {
            Properties.Settings.Default.ConsumerKey = message.MessageAttributes[OAUTH_CONSUMER_KEY];
            Properties.Settings.Default.ConsumerSecret = message.MessageAttributes[OAUTH_CONSUMER_SECRET];
            Properties.Settings.Default.OAuthToken = message.MessageAttributes[OAUTH_OATH_TOKEN];
            Properties.Settings.Default.AccessToken = message.MessageAttributes[OAUTH_ACCESS_TOKEN];
            Properties.Settings.Default.Save();
            Log("TwitterQApp configuration updated!");
        }
        #endregion

        protected override void OnReleaseResources()
        {
            if (this.twitterCtx != null)
            {
                this.twitterCtx.Dispose();
            }
        }
    }
}
